package com.bupt.kgplatform.controller;


import com.bupt.kgplatform.common.CsvUtils;
import com.bupt.kgplatform.common.FTPUtil;
import com.bupt.kgplatform.common.RetResult;
import com.bupt.kgplatform.common.TugraphUtil;
import com.bupt.kgplatform.entity.apibo.TextDataBO;
import com.bupt.kgplatform.entity.apibo.TextDataPageResult;
import com.bupt.kgplatform.entity.es.TextData;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/kgplatform/text")
public class TextController {

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @PostMapping("/upload")
    public RetResult upload(MultipartFile upfiles) throws IOException {
        try {
            List<TextDataBO> csvData = CsvUtils.getCsvData(upfiles, TextDataBO.class);
            List<TextData> datas = new ArrayList<>();
            for (TextDataBO textdata : csvData){
                TextData data = new TextData();
                data.setName(textdata.getTextname());
                data.setAuthor(textdata.getAuthor());
                data.setContent(textdata.getText());
                data.setDescription(textdata.getDescription());
                data.setCreateTime(new Date());
                data.setUpdateTime(new Date());
                datas.add(data);
            }
            elasticsearchRestTemplate.save(datas);
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
        return new RetResult(200,"导入成功");
    }

    @GetMapping("/templatedownload")
    public void download(HttpServletResponse response) throws IOException {
        OutputStream os = null;
        InputStream is = null;
        try {
            //读取流
            FTPUtil.sftpLogin();
            is = FTPUtil.Sftpdownload("texttemplate.csv","template");

            // 取得输出流
            os = response.getOutputStream();
            // 清空输出流
            response.reset();
            //跨域解决
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            //response头放文件类型
            response.addHeader("Access-Control-Expose-Headers", "fileType");

            //Content-Disposition中指定的类型是文件的扩展名，并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的，点保存后，文件以filename的值命名，
            // 保存类型以Content中设置的为准。注意：在设置Content-Disposition头字段之前，一定要设置Content-Type头字段。
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;filename="+"template.csv");
            //Header返回文件类型
            response.addHeader("fileType", "text/csv");
            //复制
            IOUtils.copy(is, response.getOutputStream());

            FTPUtil.sftpLogout();
            response.getOutputStream().flush();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        //文件的关闭放在finally中
        finally
        {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @PostMapping("/addtext")
    public RetResult addtext(TextDataBO textdata) throws IOException {
        try {
            TextData data = new TextData();
            data.setName(textdata.getTextname());
            data.setAuthor(textdata.getAuthor());
            data.setContent(textdata.getText());
            data.setDescription(textdata.getDescription());
            data.setCreateTime(new Date());
            data.setUpdateTime(new Date());
            elasticsearchRestTemplate.save(data);
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
        return new RetResult(200,"添加成功");
    }

    @PostMapping("/updatetext")
    public RetResult updatetext(@RequestParam String id,TextDataBO textdata) throws IOException {
        try {

            textdata.setUpdateTime(new Date());
            Document document = Document.create();
//            document.put("name", textdata.getTextname());
//            document.put("description", textdata.getDescription());
//            document.put("author", textdata.getAuthor());
            document.put("content", textdata.getText());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            document.put("updateTime", format.format(textdata.getUpdateTime()));
            UpdateQuery updateQuery = UpdateQuery.builder(id)
                    .withDocument(document)
                    .build();
            elasticsearchRestTemplate.update(updateQuery, IndexCoordinates.of("textdata"));
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
        return new RetResult(200,"添加成功");
    }

    @PostMapping("/deletetext")
    public RetResult deletetext(@RequestParam String id) throws IOException {
        try {
            elasticsearchRestTemplate.delete(id,TextData.class);
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
        return new RetResult(200,"添加成功");
    }

    @GetMapping("/gettextbypage")
    public RetResult gettext(int page,int pageSize,String name) throws IOException {
        try {
            TextDataPageResult res = new TextDataPageResult();
            res.dataList = new ArrayList<>();


            PageRequest pageRequest = PageRequest.of(page-1, pageSize);

            NativeSearchQueryBuilder query = new NativeSearchQueryBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            if (StringUtils.isNotBlank(name)) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("name", name));
            }


            query.withQuery(boolQueryBuilder);
            query.withPageable(pageRequest);

            SearchHits<TextData> searchHits = elasticsearchRestTemplate.search(query.build(), TextData.class);

            res.setTotal(elasticsearchRestTemplate.count(query.build(), TextData.class));
            for (SearchHit<TextData> searchHit : searchHits) {
                TextDataBO temp = new TextDataBO();
                temp.setId(searchHit.getId());
                temp.setTextname(searchHit.getContent().getName());
                temp.setDescription(searchHit.getContent().getDescription());
                temp.setAuthor(searchHit.getContent().getAuthor());
                temp.setCreateTime(searchHit.getContent().getCreateTime());
                temp.setUpdateTime(searchHit.getContent().getUpdateTime());
                temp.setText(searchHit.getContent().getContent());
                res.dataList.add(temp);
            }

            return new RetResult(200,res);
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
    }

    //测试用 无意义
    @PostMapping("/test")
    public RetResult test() throws IOException {
        try {
            TugraphUtil.deleteNodeLabel("MovieDemo2","af");
        }
        catch (Exception e){
            return new RetResult(400, e.getMessage());
        }
        return new RetResult(200,"添加成功");
    }

}
